<?php
    class GIFDecoder {
    	var $GIF_TransparentR = - 1;
    	var $GIF_TransparentG = - 1;
    	var $GIF_TransparentB = - 1;
    	var $GIF_TransparentI = 0;
    	var $GIF_buffer = array();
    	var $GIF_arrays = array();
    	var $GIF_delays = array();
    	var $GIF_dispos = array();
    	var $GIF_stream = "";
    	var $GIF_string = "";
    	var $GIF_bfseek = 0;
    	var $GIF_anloop = 0;
    	var $GIF_screen = array();
    	var $GIF_global = array();
    	var $GIF_sorted;
    	var $GIF_colorS;
    	var $GIF_colorC;
    	var $GIF_colorF;

    	function GIFDecoder($GIF_pointer) {
    		$this->GIF_stream = $GIF_pointer;
    		GIFDecoder :: GIFGetByte(6);
    		GIFDecoder :: GIFGetByte(7);
    		$this->GIF_screen = $this->GIF_buffer;
    		$this->GIF_colorF = $this->GIF_buffer[4] & 0x80 ? 1 : 0;
    		$this->GIF_sorted = $this->GIF_buffer[4] & 0x08 ? 1 : 0;
    		$this->GIF_colorC = $this->GIF_buffer[4] & 0x07;
    		$this->GIF_colorS = 2 << $this->GIF_colorC;
    		if($this->GIF_colorF == 1) {
    			GIFDecoder :: GIFGetByte(3 * $this->GIF_colorS);
    			$this->GIF_global = $this->GIF_buffer;
    		}
    		for($cycle = 1; $cycle;) {
    			if(GIFDecoder :: GIFGetByte(1)) {
    				switch($this->GIF_buffer[0]) {
    					case 0x21 :
    						GIFDecoder :: GIFReadExtensions();
    						break;
    					case 0x2C :
    						GIFDecoder :: GIFReadDescriptor();
    						break;
    					case 0x3B :
    						$cycle = 0;
    						break;
    				}
    			}
    			else{
    				$cycle = 0;
    			}
    		}
    	}

    	function GIFReadExtensions() {
    		GIFDecoder :: GIFGetByte(1);
    		if($this->GIF_buffer[0] == 0xff) {
    			for(;;) {
    				GIFDecoder :: GIFGetByte(1);
    				if(($u = $this->GIF_buffer[0]) == 0x00) {
    					break;
    				}
    				GIFDecoder :: GIFGetByte($u);
    				if($u == 0x03) {
    					$this->GIF_anloop = ($this->GIF_buffer[1] | $this->GIF_buffer[2] << 8);
    				}
    			}
    		}
    		else{
    			for(;;) {
    				GIFDecoder :: GIFGetByte(1);
    				if(($u = $this->GIF_buffer[0]) == 0x00) {
    					break;
    				}
    				GIFDecoder :: GIFGetByte($u);
    				if($u == 0x04) {
    					if($this->GIF_buffer[4] & 0x80) {
    						$this->GIF_dispos[] = ($this->GIF_buffer[0] >> 2) - 1;
    					}
    					else{
    						$this->GIF_dispos[] = ($this->GIF_buffer[0] >> 2) - 0;
    					}
    					$this->GIF_delays[] = ($this->GIF_buffer[1] | $this->GIF_buffer[2] << 8);
    					if($this->GIF_buffer[3]) {
    						$this->GIF_TransparentI = $this->GIF_buffer[3];
    					}
    				}
    			}
    		}
    	}

    	function GIFReadDescriptor() {
    		$GIF_screen = array();
    		GIFDecoder :: GIFGetByte(9);
    		$GIF_screen = $this->GIF_buffer;
    		$GIF_colorF = $this->GIF_buffer[8] & 0x80 ? 1 : 0;
    		if($GIF_colorF) {
    			$GIF_code = $this->GIF_buffer[8] & 0x07;
    			$GIF_sort = $this->GIF_buffer[8] & 0x20 ? 1 : 0;
    		}
    		else{
    			$GIF_code = $this->GIF_colorC;
    			$GIF_sort = $this->GIF_sorted;
    		}
    		$GIF_size = 2 << $GIF_code;
    		$this->GIF_screen[4] &= 0x70;
    		$this->GIF_screen[4] |= 0x80;
    		$this->GIF_screen[4] |= $GIF_code;
    		if($GIF_sort) {
    			$this->GIF_screen[4] |= 0x08;
    		}
    		if($this->GIF_TransparentI) {
    			$this->GIF_string = "GIF89a";
    		}
    		else{
    			$this->GIF_string = "GIF87a";
    		}
    		GIFDecoder :: GIFPutByte($this->GIF_screen);
    		if($GIF_colorF == 1) {
    			GIFDecoder :: GIFGetByte(3 * $GIF_size);
    			if($this->GIF_TransparentI) {
    				$this->GIF_TransparentR = $this->GIF_buffer[3 * $this->GIF_TransparentI + 0];
    				$this->GIF_TransparentG = $this->GIF_buffer[3 * $this->GIF_TransparentI + 1];
    				$this->GIF_TransparentB = $this->GIF_buffer[3 * $this->GIF_TransparentI + 2];
    			}
    			GIFDecoder :: GIFPutByte($this->GIF_buffer);
    		}
    		else{
    			if($this->GIF_TransparentI) {
    				$this->GIF_TransparentR = $this->GIF_global[3 * $this->GIF_TransparentI + 0];
    				$this->GIF_TransparentG = $this->GIF_global[3 * $this->GIF_TransparentI + 1];
    				$this->GIF_TransparentB = $this->GIF_global[3 * $this->GIF_TransparentI + 2];
    			}
    			GIFDecoder :: GIFPutByte($this->GIF_global);
    		}
    		if($this->GIF_TransparentI) {
    			$this->GIF_string .= "!\xF9\x04\x1\x0\x0".chr($this->GIF_TransparentI)."\x0";
    		}
    		$this->GIF_string .= chr(0x2C);
    		$GIF_screen[8] &= 0x40;
    		GIFDecoder :: GIFPutByte($GIF_screen);
    		GIFDecoder :: GIFGetByte(1);
    		GIFDecoder :: GIFPutByte($this->GIF_buffer);
    		for(;;) {
    			GIFDecoder :: GIFGetByte(1);
    			GIFDecoder :: GIFPutByte($this->GIF_buffer);
    			if(($u = $this->GIF_buffer[0]) == 0x00) {
    				break;
    			}
    			GIFDecoder :: GIFGetByte($u);
    			GIFDecoder :: GIFPutByte($this->GIF_buffer);
    		}
    		$this->GIF_string .= chr(0x3B);
    		$this->GIF_arrays[] = $this->GIF_string;
    	}

    	function GIFGetByte($len) {
    		$this->GIF_buffer = array();
    		for($i = 0; $i < $len; $i++) {
    			if($this->GIF_bfseek > strlen($this->GIF_stream)) {
    				return 0;
    			}
    			$this->GIF_buffer[] = ord($this->GIF_stream {
    				$this->GIF_bfseek++
    			}
    			);
    		}
    		return 1;
    	}

    	function GIFPutByte($bytes) {
    		foreach($bytes as $byte) {
    			$this->GIF_string .= chr($byte);
    		}
    	}

    	function GIFGetFrames() {
    		return ($this->GIF_arrays);
    	}

    	function GIFGetDelays() {
    		return ($this->GIF_delays);
    	}

    	function GIFGetLoop() {
    		return ($this->GIF_anloop);
    	}

    	function GIFGetDisposal() {
    		return ($this->GIF_dispos);
    	}

    	function GIFGetTransparentR() {
    		return ($this->GIF_TransparentR);
    	}

    	function GIFGetTransparentG() {
    		return ($this->GIF_TransparentG);
    	}

    	function GIFGetTransparentB() {
    		return ($this->GIF_TransparentB);
    	}
    }
?>